package top.mingyi4cjh.cms.service.impl;

import org.springframework.stereotype.Service;
import top.mingyi4cjh.cms.common.error.BusinessException;
import top.mingyi4cjh.cms.common.error.EmBusinessError;
import top.mingyi4cjh.cms.service.MailService;
import top.mingyi4cjh.cms.service.RedisService;
import top.mingyi4cjh.cms.common.utils.MailManager;
import top.mingyi4cjh.cms.common.utils.RedisPrefix;

import javax.annotation.Resource;

import static top.mingyi4cjh.cms.common.utils.Field.ONE_MINUTE;
import static top.mingyi4cjh.cms.common.utils.Field.QUARTER;

/**
 * @author MingYi
 * @program cms
 * @create 2022/04/22 00:01
 */
@Service
public class MailServiceImpl implements MailService {

    @Resource
    private MailManager mailManager;

    @Resource
    private RedisService redisService;

    @Override
    public boolean checkTtl(String address) {
        return redisService.get(RedisPrefix.MAIL_TTL.getPrefix() + address) == null;
    }

    @Override
    public boolean checkEmail(String email) {
        // 检测出传入的email格式
        return mailManager.checkEmail(email);
    }

    @Override
    public void sendOtpCode(String address, String otpCode, boolean isResent) throws BusinessException {
        // 检测出传入的email不符合格式，就不发送，直接返回异常信息就可以。
        if (!mailManager.checkEmail(address)) {
            throw new BusinessException(EmBusinessError.MAIL_FORMAT_ERROR);
        }
        String ttlKey = RedisPrefix.MAIL_TTL.getPrefix() + address;
        redisService.set(ttlKey, true, ONE_MINUTE);

        // 发送验证码给对应的邮箱
        if (isResent) {
            mailManager.resendOtpCode(address, otpCode);
        } else {
            mailManager.sendOtpCode(address, otpCode);
        }

        /*
         * 在Redis中存储email-otpCode的键值对，用于验证，设置15min的ttl，
         * 同时在Redis的set中插入一个ttl为1min的email信息，防止频繁对该邮箱发送邮件。
         */
        String key = RedisPrefix.MAIL_OTP.getPrefix() + address;
        redisService.set(key, otpCode, QUARTER);
        redisService.set(ttlKey, true, ONE_MINUTE);
    }

    @Override
    public void cleanCache(String email) {
        String ttlKey = RedisPrefix.MAIL_TTL.getPrefix() + email;
        String key = RedisPrefix.MAIL_OTP.getPrefix() + email;

        redisService.del(ttlKey);
        redisService.del(key);
    }
}

